using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Windows.Forms;
using UmlDesigner.Gui;

namespace UmlDesigner.Model
{
    [Serializable]
    class NoteWidget : ItemWidget
    {
        public string noteContents = "";

        internal override void PaintItem(Graphics e)
        {
            RecalculateSize(e);

            Point point = Position;
            Size noteSize = new Size(ClassRect.Width, ClassRect.Height);
            Point[] notePoints = new Point[5];
            notePoints[0] = new Point(point.X, point.Y + 20);
            notePoints[1] = new Point(point.X + 20, point.Y);
            notePoints[2] = new Point(point.X + noteSize.Width, point.Y);
            notePoints[3] = new Point(point.X + noteSize.Width, point.Y + noteSize.Height);
            notePoints[4] = new Point(point.X, point.Y + noteSize.Height);

            Point[] noteCornerPoints = new Point[3];
            noteCornerPoints[0] = new Point(point.X, point.Y + 20);
            noteCornerPoints[1] = new Point(point.X + 20, point.Y);
            noteCornerPoints[2] = new Point(point.X + 20, point.Y + 20);

            Color noteOutlineColour = Color.FromArgb(220, 170, 0);
            Color noteCornerColour = Color.FromArgb(230, 200, 30);

            LinearGradientBrush noteBackgroundBrush = new LinearGradientBrush(new Rectangle(point, noteSize), noteOutlineColour, Color.White, 45.0f);

            e.FillPolygon(noteBackgroundBrush, notePoints);
            e.DrawPolygon(new Pen(noteOutlineColour), notePoints);

            e.FillPolygon(new SolidBrush(noteCornerColour), noteCornerPoints);
            e.DrawPolygon(new Pen(noteOutlineColour), noteCornerPoints);

            e.DrawString(noteContents, SystemFonts.DefaultFont, new SolidBrush(Color.Black), new Point(Position.X + 25, Position.Y + 10));
        }

        private void RecalculateSize(Graphics e)
        {
            ItemSize = e.MeasureString(noteContents, SystemFonts.DefaultFont).ToSize();

            if (ItemSize.Width < 80)
            {
                ItemSize = new Size(80, ItemSize.Height);
            }
            if (ItemSize.Height < 30)
            {
                ItemSize = new Size(ItemSize.Width, 30);
            }

            ItemSize = new Size(ItemSize.Width + 35, ItemSize.Height + 20);
        }

        internal override bool IsPointWithin(Point p)
        {
            return ClassRect.Contains(p);
        }

        internal override void PaintSelectionOutline(Graphics e)
        {
            Pen stippledPen = new Pen(Color.Black);
            DrawSelection(e, stippledPen);
        }

        private void DrawSelection(Graphics e, Pen stippledPen)
        {
            float[] pattern = new float[2];
            pattern[0] = 5.0f;
            pattern[1] = 5.0f;
            stippledPen.DashPattern = pattern;
            e.DrawLine(stippledPen, new Point(ClassRect.X - 4 + 20, ClassRect.Y - 4), new Point(ClassRect.X + ClassRect.Width + 8, ClassRect.Y - 4));
            e.DrawLine(stippledPen, new Point(ClassRect.X + ClassRect.Width + 8, ClassRect.Y - 4), new Point(ClassRect.X + ClassRect.Width + 8, ClassRect.Y + ClassRect.Height + 8));
            e.DrawLine(stippledPen, new Point(ClassRect.X - 4, ClassRect.Y + ClassRect.Height + 8), new Point(ClassRect.X + ClassRect.Width + 8, ClassRect.Y + ClassRect.Height + 8));
            e.DrawLine(stippledPen, new Point(ClassRect.X - 4, ClassRect.Y - 4 + 20), new Point(ClassRect.X - 4, ClassRect.Y + ClassRect.Height + 8));
            e.DrawLine(stippledPen, new Point(ClassRect.X - 4, ClassRect.Y - 4 + 20), new Point(ClassRect.X - 4 + 20, ClassRect.Y - 4));
        }

        public override void HandleDoubleClicked(UmlControl ctrl)
        {
            NoteEditForm dlg = new NoteEditForm(this);
            dlg.ShowDialog();
        }

        public override void HandleFocusedOutline(Graphics g)
        {
            Pen stippledPen = new Pen(Color.BlueViolet, 2);
            DrawSelection(g, stippledPen);
        }

        public override void OnSetFocus()
        {

        }

        public override void OnKiilFocus()
        {

        }

        internal override bool ItemWithinArea(Rectangle rect)
        {
            return ClassRect.IntersectsWith(rect);
        }

        internal override bool IsNote()
        {
            return true;
        }

        internal override void Dump(TreeNode parent)
        {
            TreeNode noteNode = parent.Nodes.Add("Note: {" + GetHashCode() + "}");
            noteNode.Nodes.Add("Text: " + noteContents);
        }

        internal void ShallowCopyNoteWidget(NoteWidget target)
        {
            target.noteContents = noteContents;
            ShallowCopyItemWidget(target);
        }

        internal override void GenerateCode(CodeGenerationSettings settings)
        {
            settings.WriteIndentedLine("/// <summary>");

            foreach (string line in noteContents.Split('\n'))
            {
                settings.WriteIndentedLine("/// " + line);
            }

            settings.WriteIndentedLine("/// </summary>");
        }
    }
}
